package design;

import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Toolkit;

import java.util.ArrayList;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JFrame;
import javax.swing.JScrollPane;

import javax.swing.JSplitPane;

import javax.swing.JTree;

import javax.swing.event.TreeSelectionEvent;

import javax.swing.event.TreeSelectionListener;

import javax.swing.tree.DefaultMutableTreeNode;

import javax.swing.tree.DefaultTreeModel;

import org.apache.xerces.parsers.DOMParser;

import org.w3c.dom.Attr;

import org.w3c.dom.Document;

import org.w3c.dom.Node;

import org.w3c.dom.NodeList;
import javax.swing.JLabel;
import java.awt.Font;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowStateListener;
import java.awt.event.WindowEvent;

public class ViewPolicy extends JFrame implements TreeSelectionListener {

	private static final long serialVersionUID = 1L;
	private DefaultMutableTreeNode root;
	private DefaultTreeModel model;
	private JTree tree;
	private JPanel xxx;
	private JTextField txtAttribute;
	private JLabel lblAttribute;
	private JSplitPane spl;
	private JScrollPane sp;
	private JTextArea txtDescription;
	private JScrollPane scrollPane;
	private int width;
	private Font font = new Font("Times New Roman", Font.PLAIN, 12);
	private Font bold = new Font("Times New Roman", Font.BOLD, 12);	
	private boolean stateMax = false;

	/** add listener de xu ly su thay doi cua so */
	WindowStateListener listener = new WindowAdapter() {
		public void windowStateChanged(WindowEvent evt) {
			if (evt.getNewState() == Frame.MAXIMIZED_BOTH) {
				Toolkit toolkit = Toolkit.getDefaultToolkit();
				Dimension dim = toolkit.getScreenSize();
				stateMax = true;
				spl.setBounds(0, 0, (int) dim.getWidth() , (int) dim.getHeight() - 58);
				getContentPane().add(spl);			
			}
			else{
				spl.setBounds(0, 0, 700, 600);
				getContentPane().add(spl);		
				stateMax = false;
			}
		}
	};

	/** Tao frame */
	public void init() {
		setSize(703, 640);
		this.setLocationRelativeTo(null);
		root = new DefaultMutableTreeNode("XML Document");
		model = new DefaultTreeModel(root);
		tree = new JTree(model);
		tree.addTreeSelectionListener(this);
		txtAttribute = new JTextField();
		txtAttribute.setBounds(0, 0, 0, 0);
		txtAttribute.setEditable(false);
		xxx = new JPanel();
		getContentPane().setLayout(null);
		xxx.setLayout(null);

		sp = new JScrollPane(tree);		
		sp.setPreferredSize(new Dimension(250, 250));
		spl = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, sp, xxx);

		spl.setBounds(0, 0, 700, 600);
		getContentPane().add(spl);
	}

	/** Constructor view mot file */
	public ViewPolicy(String fileName) {
		super("View Policy " + fileName);
		
		init();
		buildtree(fileName);
		tree.expandRow(0);
		this.addWindowStateListener(listener);
	}

	/** Parse uri to Document */
	void buildtree(String uri) {
		try {
			DOMParser parser = new DOMParser();
			parser.parse(uri);
			Document doc = parser.getDocument();
			addNode(doc, root);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@SuppressWarnings("null")
	/** add cac node tu document sang Jtree*/
	void addNode(Node xmlNode, DefaultMutableTreeNode treeNode) {
		if (xmlNode == null)
			return;

		int type = xmlNode.getNodeType();
		MyNode mn = null;
		switch (type) {
		case Node.DOCUMENT_NODE: {
			addNode(((Document) xmlNode).getDocumentElement(), treeNode);
			break;
		}

		case Node.ELEMENT_NODE: {
			mn = new MyNode(xmlNode.getNodeName(), xmlNode.getNodeValue(), null);
			int length = (xmlNode.getAttributes() != null) ? xmlNode
					.getAttributes().getLength() : 0;
			ArrayList<Attr[]> al = new ArrayList<Attr[]>();
			Attr[] attributes = new Attr[length];
			for (int i = 0; i < length; i++) {
				attributes[i] = (Attr) xmlNode.getAttributes().item(i);
				al.add(attributes);
			}
			mn.setAttributes(al);// cap nhat
			DefaultMutableTreeNode tn = new DefaultMutableTreeNode(mn);
			treeNode.add(tn);
			NodeList childNodes = xmlNode.getChildNodes();
			if (childNodes != null) {
				length = childNodes.getLength();
				for (int i = 0; i < length; i++) {
					addNode(childNodes.item(i), tn);
				}
			}
			break;
		}

		case Node.CDATA_SECTION_NODE: {
			String x = "<![CDATA[" + xmlNode.getNodeValue() + "]]>";
			mn.setNodeValue(x);
			break;
		}

		case Node.TEXT_NODE: {
			String newText = xmlNode.getNodeValue().trim();
			((MyNode) treeNode.getUserObject()).setNodeValue(newText);
			break;
		}

		case Node.PROCESSING_INSTRUCTION_NODE: {
			String text = xmlNode.getNodeValue();
			((MyNode) treeNode.getUserObject()).setNodeValue(text);
			break;
		}
		}
	}

	@Override
	/** Xu ly thay doi gia tri tren Tree */
	public void valueChanged(TreeSelectionEvent e) {
		try {
			DefaultMutableTreeNode selNode = (DefaultMutableTreeNode) e
					.getPath().getLastPathComponent();
			Object obj = selNode.getUserObject();
			if (obj instanceof MyNode) {
				xxx.removeAll();
				spl.add(JSplitPane.RIGHT, xxx);
				MyNode node = (MyNode) obj;
				ArrayList<Attr[]> attrs = node.getAttributes();

				int j = 0;
				if(!stateMax)	width = 200;
				else	width = 300;
				/** Neu node co attribute thi the hien cac attribute tren giao dien*/
				if (attrs != null && attrs.size() > 0) {
					for (int i = 0; i <= attrs.size() - 1; i++) {
						for (j = 0; j < attrs.get(i).length; j++) {
							if (!(attrs.get(i)[j].getName().contains(":"))
									&& !(attrs.get(i)[j].getName()
											.equals("xmlns"))) {
								
								lblAttribute = new JLabel("Attribute");
								lblAttribute.setBounds(15, 34 + 85 * j, width, 29);
								//lblAttribute.setFont(font);
								lblAttribute.setFont(bold);
								lblAttribute.setText(attrs.get(i)[j].getName());
								xxx.add(lblAttribute);

								txtAttribute = new JTextField();
								txtAttribute.setText(attrs.get(i)[j].getValue());
								txtAttribute.setFont(font);
								txtAttribute.setBounds(15, 62 + 85 * j, width + 150 , 34);
								xxx.add(lblAttribute);
								xxx.add(txtAttribute);
								spl.add(JSplitPane.RIGHT, xxx);
							}
						}
					}
				}
				
				/** Neu node khong co attribute thi se the hien gia tri cua node do */
				if (node.getNodeValue() != null) {
					if (!node.getNodeValue().equals("")) {
						lblAttribute = new JLabel("Attribute");
						lblAttribute.setBounds(15, 34 + 85 * j, width, 22);
						lblAttribute.setFont(bold);
						lblAttribute.setText(node.getNodeID());
						xxx.add(lblAttribute);
						if (node.getNodeID().equals("Description")) {
							txtDescription = new JTextArea(5, 20);
							txtDescription.setFont(font);
							txtDescription.setText(node.getNodeValue());
							scrollPane = new JScrollPane(txtDescription);
							scrollPane.setBounds(15, 59 + 85 * j, width + 156, 100);
							xxx.add(scrollPane);
						} else {
							txtAttribute = new JTextField();
							txtAttribute.setFont(font);
							txtAttribute.setBounds(15, 59 + 85 * j, width + 150, 34);
							txtAttribute.setText(node.getNodeValue());
							xxx.add(txtAttribute);
						}
						spl.add(JSplitPane.RIGHT, xxx);
					}
				}
			}
		} catch (Exception e1) {
			e1.printStackTrace();
		}
	}
}